// MMU components
#define TARGET_ANY					0x00
#define TARGET_L1I					0x01
#define TARGET_L1D					0x02
#define TARGET_L2					0x04
#define TARGET_L3					0x08
#define TARGET_ROM					0x10
#define TARGET_RAM					0x20
#define TARGET_DEV					0x40
#define TARGET_CACHE				0x0F

// MMU types
typedef uint8_t						mmu_bool;
typedef uint8_t						mmu_source;
typedef uint8_t						mmu_target;
typedef uint8_t						mmu_action;
typedef uint8_t						mmu_options;
typedef uint8_t						mmu_amode;
typedef uint8_t						mmu_prot;
typedef uint16_t					mmu_policy;
typedef uint8_t						cache_policy;

// MMU datastructures
typedef struct mmu_op				mmu_op;
typedef struct cache_statistics		cache_stats;
typedef struct mmu_statistics		mmu_stats;
typedef struct mmu_region			mmu_region;

// MMU policies
#define POLICY_READTHROUGH			0x0001	// Simul. memory read/cache store
#define POLICY_WRITETHROUGH			0x0002	// On write, write data back to memory
#define POLICY_WRITEALLOCATE		0x0004	// On write miss read line into cache
#define POLICY_INSTANT_TLB			0x0008	// No delay on TLB read
#define POLICY_MAP_TLB				0x0010	// Enable the TLB
#define POLICY_MAP_FIXED			0x0020	// Use fixed address mapping
#define POLICY_CACHE_OPAQUE			0x0040	// No cache instructions
#define POLICY_CACHE_COHERENT		0x0080	// Enable cache coherency

#define POLICY_HARVARD_MEMORY		0x0100	// Use a separate I/D memories
#define POLICY_NO_BUS_Q				0x0200	// Ignore bus structural hazards
#define POLICY_NO_RAM_Q				0x0400	// Ignore RAM structural hazards
#define POLICY_NO_ROM_Q				0x0800	// Ignore ROM structural hazards
#define POLICY_NO_ARBITERS			0x1000	// No arbitration, access pass through

// MMU Stalls
#define STALL_STRUCT_L1I			0x01
#define STALL_STRUCT_L1D			0x02
#define STALL_STRUCT_L2				0x03
#define STALL_STRUCT_L3				0x04
#define STALL_STRUCT_BUS			0x05
#define STALL_STRUCT_RAM			0x06
#define STALL_STRUCT_ROM			0x07
#define STALL_STRUCT_DEVICE			0x08

struct mmu_region {
	sim_cycle		read_delay;				// Read latency of region
	sim_cycle		write_delay;			// Write latency of region
	sim_addr		start;					// Start address of region
	sim_addr		end;					// End address of region
};

struct mmu_context {
	mmu_policy		policy;					// MMU policies

	mmu_stall		s_cause;				// if a stall occurs the reason is set here
	mmu_except		*ex_context;			// if an exception occurs the context is saved here

	mmu_stats		*cpu_stats;				// statistics about CPU access to MMU
	mmu_stats		*dma_stats;				// statistics about DMA access to MMU

	TLB				*tlb;					// TLB, if required for address translation
	sim_cycle		tlb_delay;
	mmu_q			tlb_q;

	mmu_cache		*L1I;					// L1 instruction cache and queue
	mmu_cache		*L1D;					// L1 data cache and queue
	mmu_cache		*L2;					// L2 cache and queue
	mmu_cache		*L3;					// L3 cache and queue

	sim_size		dma_clients;			// number of distinct DMA clients

	sim_size		ndev;					// number of memory mapped devices
	mmu_dev			*devs;					// memory mapped devices
	
	mmu_region		ram;					// R/W memory
	mmu_region		rom;					// Read only memory (generally slower too)

	phys_mem		memory;					// combined RAM/ROM data structure
};

